package com.chenjl.trace.aspect;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.caucho.hessian.client.HessianProxy;
import com.chenjl.trace.Tracer;
import com.chenjl.trace.enums.AnnotationEnum;
import com.chenjl.trace.enums.SpanTypeEnum;
import com.chenjl.trace.model.Endpoint;
import com.chenjl.trace.model.Span;
/**
 * 使用aspect对Hessian Client进行trace埋点
 * 2018-9-7 14:01:332
 * @author chenjinlong
 */
@Aspect
public class HessianAspect {
	private static final Logger log = LoggerFactory.getLogger(HessianAspect.class);
	
	@Pointcut("execution(public * com.caucho.hessian.client.HessianProxy.invoke(..))")
	public void getPointCut() {
		
	}
	
	@Around(value="getPointCut()")
	public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		Span rootSpan = Tracer.getRootSpan();
		if(rootSpan == null) {
			//无埋点的正常请求
			return proceedingJoinPoint.proceed();
		}
		
		
		Object result = null;
		Throwable throwable = null;
		
		HessianProxy hessianProxy = (HessianProxy) proceedingJoinPoint.getTarget();
		String url = hessianProxy.getURL().toString();
		
		Method method = (Method) proceedingJoinPoint.getArgs()[1];
		String serviceName = method.getDeclaringClass().getName();
		String methodName = method.getName();
		
		Endpoint endpoint = new Endpoint();
		endpoint.setServiceName("hessian request");
		endpoint.setHost(url);
		String spanId = Tracer.begin(rootSpan.getTraceId(),rootSpan.getId(),serviceName+"."+methodName,endpoint,AnnotationEnum.CLIENT_SEND,SpanTypeEnum.HESSIAN_SERVICE);
		
		boolean hasExceptionFlag = false;
		log.info(" -->--Hessian invoke begin, url : {} ,serviceName : {} ,methodName : {}",url,serviceName,methodName);
		try {
			result = proceedingJoinPoint.proceed();
		}
		catch (Throwable e) {
			hasExceptionFlag = true;
			throwable = e;
		}
		
		Map<String,String> datas = new HashMap<String,String>(2);
		datas.put("hasException",String.valueOf(hasExceptionFlag));
		Tracer.end(spanId,endpoint,AnnotationEnum.CLIENT_RECEIVE,datas);
		log.info(" -->--Hessian invoke end, url : {} ,serviceName : {} ,methodName : {}，error: {}",url,serviceName,methodName,throwable!=null);
		
		if(throwable != null) {
			throw throwable;
		}
		return result;
	}
}